/*
  学习目标：React中复用组件逻辑的三种方式- 小结
    1.Render props
       本质：父传子技术的使用
       步骤：1. props接受一个render属性，render是一个函数
            2. render返回一段JSX
            3. render的形参是封装的数据和方法
       缺点：1. 增加组件嵌套结构  2. 增加理解成本
    2. HOC
       本质：是一个函数接收组件，返回一个封装过的组件
       步骤：
            1. 定义一函数，接收一个组件
            2. 内置一个组件，封装逻辑， 并且返回
            3. 内置组件，渲染接收的组件，通过父传子传递数据
       缺点：1. 增加组件嵌套结构 
    3. 👍自定义hooks 
*/

import React, { useState } from 'react';

export default function App() {
  return (
    <div>
      <Header></Header>
      <Main></Main>
    </div>
  );
}

// 1. 定义一个hooks: hooks内封装逻辑
// 💥 hooks就一个函数，名字要以useXxxx开头
// 💥 自定义hooks内，可以调用其它的hooks
function useMouse() {
  const [mouse, setMouse] = useState({ x: 0, y: 0 });

  const handleMouseMouse = (e) => {
    setMouse({ x: e.clientX, y: e.clientY });
  };

  return { mouse, handleMouseMouse };
}
// 2. 在其它组件内调用hooks
function Header() {
  const { mouse, handleMouseMouse } = useMouse();

  return (
    <h1 onMouseMove={handleMouseMouse}>
      x-{mouse.x}
      <span>y-{mouse.y}</span>
      <Son></Son>
    </h1>
  );
}

function Main() {
  const { mouse, handleMouseMouse } = useMouse();
  console.log('mouse  ----->  ', mouse);
  return (
    <div onMouseMove={handleMouseMouse}>
      <h1>我是Main组件</h1>
      <h2>{mouse.x}</h2>
      <h2>{mouse.y}</h2>
    </div>
  );
}

function Son() {
  const { mouse, handleMouseMouse } = useMouse();
  return <h1>我是Son组件</h1>;
}
